<?php
class Zwei_Utils_FileHandler {
	private $userDir			= false;
 
	private $allowedExtensions 	= array('jpg','jpeg','gif','png');
	private $allowedMimes 		= array('image/jpg','image/jpeg','image/gif','image/png'); //requires $allowImagesOnly;
 
	private $renameFiles		= true; //each uploaded file will have a unique id prepended to it's filename
	private $allowImagesOnly	= true;
	private $checkMimes			= true; //requires $allowImagesOnly;
	private $maximumFileSize	= 0;
 
	private $systemErrors = array(
			'noUploaddir'		=>	'Upload directory Does not exist.',
			'noFiles'	=>	'No Files were uploaded.',
			'extension'	=>	'Only the following file types are allowed',
			'imagesOnly'	=> 	'does not appear to be an image file. - please try another file.',
			'mime'		=>	'This file\'s mimetype is not allowed - please try another file',
			'unknown'	=>	'Unknown error uploading file.',
			'maximumFileSize'	=>	'exceeds the maximum file size - '
	);
	private $uploadErrors 		= array(
		    UPLOAD_ERR_INI_SIZE 	=> 	'The uploaded file exceeds the upload_max_filesize directive -- (UPLOAD_ERR_INI_SIZE)',
		    UPLOAD_ERR_FORM_SIZE 	=> 	'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form -- (UPLOAD_ERR_FORM_SIZE)',
		    UPLOAD_ERR_PARTIAL 		=> 	'The uploaded file was only partially uploaded -- (UPLOAD_ERR_PARTIAL)',
		    UPLOAD_ERR_NO_FILE 		=>	'No file was uploaded -- (UPLOAD_ERR_NO_FILE)',
		    UPLOAD_ERR_NO_TMP_DIR 	=> 	'Missing a temporary folder -- (UPLOAD_ERR_NO_TMP_DIR)',
		    UPLOAD_ERR_CANT_WRITE 	=> 	'Failed to write file to disk -- (UPLOAD_ERR_CANT_WRITE)',
		    UPLOAD_ERR_CANT_WRITE 	=> 	'File upload stopped by extension -- (UPLOAD_ERR_CANT_WRITE)'
	);
 
	public function __construct(){
		set_time_limit(360);
		if (!strlen(session_id())) session_start();
	}
 
	public function setAllowedExtensions(Array $extensions){
		$this->allowedExtensions = $extensions; 
	}
 
	public function setCheckMimes($value){//this requires $allowImagesOnly to work;
		$this->checkMimes = $value;
	}
 
	public function setAllowedMimes(Array $allowedMimes){//this requires $allowImagesOnly to work;
		$this->allowedMimes = $allowedMimes; 
	}
 
	public function setRenameFiles($value){
		$this->renameFiles = $value;
	}
 
	public function setAllowImagesOnly($value){
		$this->allowImagesOnly	= $value;
	}
	public function setMaximumFileSize($value){
		$this->maximumFileSize	= $value;
	}
 
	private function checkFiles(){
		$RV= Array('upload'=>array(),'errors'=>array());
		$pattern = '/\.'.implode($this->allowedExtensions,'|\.').'$/i'; 
 
		if (!count($_FILES)){
			$RV['errors']['system']= $this->systemErrors['noFiles'];
			return $RV; 
		}
 
		foreach($_FILES as $key=>$value){
			$filename = $_FILES[$key]['name'] ? $_FILES[$key]['name'] : '';
 
			//php errors 
			if($_FILES[$key]['error']){
				$errorCode = $_FILES[$key]['error'];
				if($errorCode !== UPLOAD_ERR_OK){
					Zwei_Utils_Debug::write($errorCode);
			    	if(isset($this->uploadErrors[$errorCode])){
				        $RV['errors'][$key] = $filename.' : '.$this->uploadErrors[$errorCode];
				    } else {
				        $RV['errors']['system'] = $filename.' : '.$this->systemErrors['unknown'];
			    	}
				}
				continue;
			}
 
			/* type check */
			if (!preg_match($pattern,$_FILES[$key]['name'])){
				$RV['errors'][$key] = $filename .' : '.$this->systemErrors['extension'].' : '.implode($this->allowedExtensions,', ') ;
				continue;
			}
 
			if ($this->allowImagesOnly){
				$info = @getimagesize($_FILES[$key]['tmp_name']);
				if(!$info){
					$RV['errors'][$key] = $filename.' : '.$this->systemErrors['imagesOnly'];
				}
				if ($this->checkMimes){
					if(!in_array($info['mime'],$this->allowedMimes)){
						$RV['errors'][$key] = $filename.' : '.$this->systemErrors['mime'] .' : '.implode($this->allowedMimes,', ');
					}
				}
			}
			/* file size */
			if ($this->maximumFileSize){
				if (strstr($this->maximumFileSize,'M')){
					$max = (int)$this->maximumFileSize*1048576;
				}else{
					$max = $this->maximumFileSize;
				}
				if($_FILES[$key]['size'] > $max){
					$RV['errors'][$key] = $filename.' : '.$this->systemErrors['maximumFileSize'].$this->maximumFileSize;
				}
			}	
		}
		return $RV; 
	}
 
	public function saveFilesToUserDir($dir){
		$this->userDir = $dir; 
		$RV = Array();
 
		$RV = $this->checkFiles();
 
		if (!is_dir($this->userDir)){
			$RV['errors']['system']= $this->systemErrors['noUploadDir'];
		}
 
		if (!count($RV['errors'])){
			$_SESSION['fileNames'] = Array();
			foreach($_FILES as $key=>$value){
				//create guid to rename file and write it to session for access 
				$extra = $this->renameFiles ? uniqid().'-' : '';
				$newName = $extra.$_FILES[$key]['name'];
				$uploadfile = $this->userDir.$newName;
 
				if(!array_key_exists($key,$RV)){   // if it hasn't already been invalidated by checkFile
					set_time_limit(360);
					$_SESSION['fileNames'][] = $newName;
					if (move_uploaded_file($_FILES[$key]['tmp_name'],$uploadfile)) {
					  	$RV['upload'][$key] = 1; 
					} 
				}
			}
		}
		if (!count($RV)) $RV['empty'] = 1;
		return json_encode($RV);
	}
}


